package com.topc.others.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.xml.bind.v2.TODO;
import com.topc.base.exception.Asserts;
import com.topc.base.model.PageParams;
import com.topc.base.model.PageResult;
import com.topc.base.utils.PageUtils;
import com.topc.others.mapper.CompetitionUserMidMapper;
import com.topc.others.model.dto.SaveCompetitionComposeDto;
import com.topc.others.model.po.CompetitionApplyInfo;
import com.topc.others.model.po.CompetitionInfo;
import com.topc.others.model.po.CompetitionUserMid;
import com.topc.others.model.vo.CompetitionApplyShowVo;
import com.topc.others.service.ICompetitionInfoService;
import com.topc.others.service.ICompetitionUserMidService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 用户竞赛关系表 服务实现类
 * </p>
 *
 * @author Gogoing
 */
@Slf4j
@Service
public class CompetitionUserMidServiceImpl extends ServiceImpl<CompetitionUserMidMapper, CompetitionUserMid> implements ICompetitionUserMidService {

    @Autowired
    private ICompetitionInfoService competitionInfoService;

    @Autowired
    private CompetitionUserMidMapper competitionUserMidMapper;

    @Override
    public void saveUserInfo(SaveCompetitionComposeDto saveCompetitionComposeDto) {
        LambdaQueryWrapper<CompetitionUserMid> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompetitionUserMid::getUserNumber,saveCompetitionComposeDto.getUserNumber());
        List<CompetitionUserMid> list = this.list(queryWrapper);
        if (ObjectUtil.isNotEmpty(list)){
            if (list.get(0).getStatus().equals(-1)){
                Asserts.fail("用户被禁赛中");
            }
            Asserts.fail("用户已报名");
        }
        CompetitionUserMid competitionUserMid = new CompetitionUserMid();
        BeanUtil.copyProperties(saveCompetitionComposeDto,competitionUserMid);
        boolean save = save(competitionUserMid);
        if (!save) Asserts.fail("报名失败");
    }

    @Override
    public void deleteUserInfoById(Long id, String userNumber) {
        LambdaQueryWrapper<CompetitionUserMid> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompetitionUserMid::getId,id)
                .eq(CompetitionUserMid::getUserNumber,userNumber);
        boolean remove = this.remove(queryWrapper);
        if (!remove)Asserts.fail("取消失败");
    }

    @Override
    public void updateApplyInfoById(Long id,String userNumber) {
        //TODO:此处还可以进行用户是否存在的检定
        //竞赛ID检索用户状态
        CompetitionApplyInfo competitionApplyInfo =competitionUserMidMapper.getApplyInfo(id,userNumber);
        //如果竞赛Id查询为空
        if (ObjectUtil.isEmpty(competitionApplyInfo)||ObjectUtil.isEmpty(competitionApplyInfo.getCompetitionId())){
            Asserts.fail("竞赛不存在");
        }
        //时间判断-比赛结束时无法执行
        LocalDateTime now = LocalDateTime.now();
        if (now.isAfter(competitionApplyInfo.getEndTime())){
            Asserts.fail("比赛已结束，无法修改报名状态");
        }
        //时间段-比赛结束前
        //如果已经有报名记录
        if (!ObjectUtil.isEmpty(competitionApplyInfo.getId())){
            Integer status = competitionApplyInfo.getStatus();
            switch (status){
                //交卷用户不可修改
                case 1:Asserts.fail("用户已交卷，无法修改");
                        break;
                //禁赛用户不可修改
                case -1:Asserts.fail("用户处于禁赛状态,无法修改");
                        break;
                //如果用户在比赛进行中且已经报名，则无法退出报名
                case 0:{
                    if(now.isAfter(competitionApplyInfo.getStartTime())){
                        Asserts.fail("比赛进行中，已报名");
                    }else{
                        this.removeById(competitionApplyInfo.getId());
                    }
                    break;
                }
            }
        }else{
            //仅未查询到竞赛报名信息,执行报名,存入报名信息(userNumber，competitionId)
            CompetitionUserMid competitionUserMid = new CompetitionUserMid();
            competitionUserMid.setCompetitionId(id);
            competitionUserMid.setUserNumber(userNumber);
            competitionUserMid.setType(1);
            competitionUserMid.setScoreComposeMid("0");
            boolean save = this.save(competitionUserMid);
            if(!save) {
                Asserts.fail("竞赛报名异常，请重试");
            }

        }
    }

    @Override
    public PageResult<CompetitionApplyShowVo> getApplyInfoByPage(PageParams pageParams, Long id) {
        Page<CompetitionApplyShowVo> competitionApplyShowVoPage =this.getBaseMapper().searchPage(pageParams.page(),id);
        return PageUtils.pageToResult(competitionApplyShowVoPage);
    }

    @Override
    public String getApplyInfoByUserNumber(Long competitionId, String userNumber) {
        LambdaQueryWrapper<CompetitionUserMid> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompetitionUserMid::getUserNumber,userNumber)
                    .eq(CompetitionUserMid::getCompetitionId,competitionId);
        List<CompetitionUserMid> list = this.list(queryWrapper);
        CompetitionUserMid competitionUserMid = list.get(0);
        if (ObjectUtil.isEmpty(competitionUserMid)) return "未报名";
        if (competitionUserMid.getStatus() == -1) return "禁赛中";
        return "已报名";
    }

    @Override
    public boolean updateScore(String userNumber, Long competitionId, Integer score) {
        LambdaUpdateWrapper<CompetitionUserMid> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CompetitionUserMid::getScore,score)
                .eq(CompetitionUserMid::getUserNumber,userNumber)
                .eq(CompetitionUserMid::getCompetitionId,competitionId);
        return this.update(updateWrapper);
    }

    @Override
    public void updateCompetitionFinished(Long id, String userNumber) {
        //时间判定:比赛结束后不可交卷，比赛开始前也不可交卷
        LambdaQueryWrapper<CompetitionInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(CompetitionInfo::getStartTime,CompetitionInfo::getEndTime)
                .eq(CompetitionInfo::getId,id);
        CompetitionInfo competitionInfo = competitionInfoService.getOne(queryWrapper);
        if (ObjectUtil.isEmpty(competitionInfo)){
            Asserts.fail("竞赛不存在");
        }
        LocalDateTime now = LocalDateTime.now();
        if (now.isAfter(competitionInfo.getEndTime())){
            Asserts.fail("竞赛已结束,不可交卷");
        }
        if (now.isBefore(competitionInfo.getStartTime())){
            Asserts.fail("竞赛未开始,不可交卷");
        }
        LambdaUpdateWrapper<CompetitionUserMid> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CompetitionUserMid::getStatus,1)
                .eq(CompetitionUserMid::getUserNumber,userNumber)
                .eq(CompetitionUserMid::getCompetitionId,id);
        boolean update = this.update(updateWrapper);
        if (!update){
            Asserts.fail("交卷失败");
        }
    }
}
